home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
ww_tv.exe
/
WRAP.ASM
< prev
Wrap
Assembly Source File
|
1992-02-11
|
23KB
|
805 lines
;/**************************************************************************/
;/* */
;/* Copyright (c) 1991 Primatech Inc. */
;/* */
;/* All Rights Reserved */
;/* */
;/**************************************************************************/
;/*------------------------------------------------------------*/
;/* filename - wrap.asm */
;/* */
;/* function(s) */
;/* TEditor::doWordWrapBuffer */
;/*------------------------------------------------------------*/
;Created: 12 November 1991 by Jeffrey A. Hottle
IDEAL
JUMPS
MODEL LARGE, PROLOG
INCLUDE "TVWRITE.INC"
PUBLIC @TEditor@doWordWrapBuffer$qususns
EXTRN @TEditor@changeBufSize$qs:PROC
CR = 0Dh
LF = 0Ah
CODESEG
MACRO AdvancePtr
LOCAL @@OK
inc BX
cmp BX,[ES:DI+TEditorCurPtr]
jne @@OK
add BX,[ES:DI+TEditorGapLen]
@@OK:
ENDM
;ushort TEditor::doWordWrapBuffer( ushort start_ofs,
; ushort min_chars,
; int* line_delta )
;assume:
; line_delta is initialized
; start_ofs is beginning of a line
; at least 2 lines or min_chars will be processed
;
PROC @TEditor@doWordWrapBuffer$qususns
ARG thisPtr:FAR PTR, StartOfs:WORD, MinChars:WORD, LineDelta:PTR WORD
USES DS,SI,DI
LOCAL Delta:WORD, CharCt:WORD, LineCt:WORD, RealDS:WORD
LOCAL BufChg:BYTE, LineChg:BYTE, LineStart:WORD, DelLastCR:BYTE
LOCAL WrapPos:WORD, WrapDX:WORD, WrapCharCt:WORD
ASSUME DS:nothing, ES:nothing
xor AX,AX
mov [Delta],AX
mov [CharCt],AX
mov [LineCt],AX
mov [BufChg],AL
mov [RealDS],DS ;save original DATASEG
les DI,[thisPtr]
lds SI,[ES:DI+TEditorBuffer] ;DS:SI = buffer
mov BX,[StartOfs]
; update BX if it is sitting at the start of the gap
cmp BX,[ES:DI+TEditorCurPtr]
jne ScanLine
add BX,[ES:DI+TEditorGapLen]
ScanLine:
;----------------------------------
; scan to find line break position
;----------------------------------
xor DX,DX ;DH = CR count, DL = previous buffer char
xor CX,CX ;CX = current x position
cld
xor AX,AX
mov [LineChg],AL
mov [DelLastCR],AL
mov [WrapPos],AX
mov [LineStart],BX
jmp short ScanSkip
ScanNext:
mov AH,AL ;save previous line character
AdvancePtr ;advance pointer
ScanSkip:
mov DL,AL ;save previous buffer character
cmp BX,[ES:DI+TEditorBufSize];check for end of buffer
jae BufEnd
inc CX ;advance column number
inc [CharCt]
mov AL,[SI+BX] ;get character from buffer
cmp AL,CR ;is this character a CR?
jne NotCR
AdvancePtr
cmp [BYTE PTR SI+BX],LF ;yes, is it CR+LF? (hard return)
jne JustCR
AdvancePtr ;hard return, skip LF
inc [CharCt]
jmp DelAllCR ;remove all soft returns from this line
JustCR:
inc DH ;bump soft-return count
dec CX ;don't count this as a column
jmp ScanSkip
NotCR:
cmp AL,' ' ;check for space
je ScanNext ;skip spaces
cmp AL,9 ;check for tab
jne NotSpace
mov AX,CX ;adjust column number to next tab position
dec AX
div [BYTE PTR ES:DI+TEditorTabSize] ;AH = # past previous tab stop
mov AL,[ES:DI+TEditorTabSize]
sub AL,AH
cbw
add CX,AX ;CX = column number of next tab stop
mov AL,' '
jmp ScanNext
NotSpace:
cmp AH,' ' ;non-space, check prev for space or hyphen
je SetBreak
cmp AH,'-'
je SetBreak
cmp CX,[ES:DI+TEditorRMargin];no break here, check if past end of line
jbe ScanNext ;not past end
cmp [WrapPos],0 ;past end, have we found a break yet?
jnz BreakPos ;yes
jmp BreakPosGo ;no, use this position
SetBreak:
mov [WrapPos],BX
mov [WrapDX],DX
push AX
mov AX,[CharCt]
mov [WrapCharCt],AX
pop AX
cmp CX,[ES:DI+TEditorRMargin];is this the end of the line?
jbe ScanNext ;no
;---------------------------------------------------------
; break position found, check if line already breaks here
;---------------------------------------------------------
BreakPos:
mov BX,[WrapPos] ;set current pointer back to wrap position
mov DX,[WrapDX] ;get previous buffer char & CR count
mov AX,[WrapCharCt] ;set proper character count
mov [CharCt],AX
BreakPosGo:
dec [CharCt] ;adjust count for character after the break
cmp DH,1 ;check for 1 CR found
jne FixBuffer
cmp DL,CR ;check if CR is previous char in buffer
je NextLine ;it is, no change to buffer needed
jmp FixBuffer
;----------------------------------------
; end of buffer, remove all soft returns
;----------------------------------------
BufEnd:
or DH,DH ;any soft-returns in this line?
jz Success ;no, we're done
;--------------------------------------
; remove all soft returns in this line
;--------------------------------------
DelAllCR:
mov [DelLastCR],1
;----------------------------------------------------------------
; update buffer removing soft returns, setting new one if needed
;----------------------------------------------------------------
FixBuffer:
mov CX,BX ;save ending position
or DH,DH ;are there any CRs?
jz NoCR
mov BX,[LineStart] ;get start-of-line position
FindCR:
cmp [BYTE PTR SI+BX],CR ;is this character a CR?
je FoundCR
AdvancePtr ;no, try next character
jmp FindCR
FoundCR:
dec DH ;adjust CR count
jnz DeleteIt ;not last one yet
cmp [DelLastCR],0 ;delete last CR?
jz LastCR
DeleteIt:
dec [Delta] ;adjust line delta value
mov [LineChg],1
mov [BufChg],1
; compress text at BX, updating ptr in CX and other object pointers
call CompressBuf
or DH,DH
jnz FindCR
LastCR:
; shift text (if needed) to put CR at end of line
cmp [DelLastCR],0 ;do we want a CR on this line?
jnz RightPlace ;no
cmp DL,CR ;check if we have a CR in the right place
je RightPlace
; shift text at BX thru CX and put CR in the hole
mov [LineChg],1
mov [BufChg],1
call ShiftBuf
mov BX,CX ;put CR in the hole
mov [BYTE PTR SI+BX],CR
AdvancePtr ;skip over that location
jmp NextLine
NoCR:
cmp [DelLastCR],0 ;do we want a CR on this line?
jnz RightPlace ;no
; expand buffer at end and insert CR in hole
mov BX,CX
mov AX,[RealDS]
call ExpandBuf
or AX,AX ;check for expand failure
jz Failure
mov [LineChg],1
mov [BufChg],1
inc [Delta] ;adjust line delta value
mov [BYTE PTR SI+BX],CR
RightPlace:
mo